package com.chenqq.camerademo.camera.bean;

import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbInterface;

public class DeviceFilter {

    // USB Vendor ID (or -1 for unspecified)
    public int mVendorId;
    // USB Product ID (or -1 for unspecified)
    public int mProductId;
    // USB device or interface class (or -1 for unspecified)
    public int mClass;
    // USB device subclass (or -1 for unspecified)
    public int mSubclass;
    // USB device protocol (or -1 for unspecified)
    public int mProtocol;
    // USB device manufacturer name string (or null for unspecified)
    public String mManufacturerName;
    // USB device product name string (or null for unspecified)
    public String mProductName;
    // USB device serial number string (or null for unspecified)
    public String mSerialNumber;
    // set true if specific device(s) should exclude
    public boolean isExclude;

    public DeviceFilter(final int vid, final int pid, final int clasz, final int subclass,
                        final int protocol, final String manufacturer, final String product, final String serialNum) {
        this(vid, pid, clasz, subclass, protocol, manufacturer, product, serialNum, false);
    }

    public DeviceFilter(final int vid, final int pid, final int clasz, final int subclass,
                        final int protocol, final String manufacturer, final String product, final String serialNum, final boolean isExclude) {
        mVendorId = vid;
        mProductId = pid;
        mClass = clasz;
        mSubclass = subclass;
        mProtocol = protocol;
        mManufacturerName = manufacturer;
        mProductName = product;
        mSerialNumber = serialNum;
        this.isExclude = isExclude;
    }

    public DeviceFilter(final UsbDevice device) {
        this(device, false);
    }

    public DeviceFilter(final UsbDevice device, final boolean isExclude) {
        mVendorId = device.getVendorId();
        mProductId = device.getProductId();
        mClass = device.getDeviceClass();
        mSubclass = device.getDeviceSubclass();
        mProtocol = device.getDeviceProtocol();
        mManufacturerName = null;    // device.getManufacturerName();
        mProductName = null;        // device.getProductName();
        mSerialNumber = null;        // device.getSerialNumber();
        this.isExclude = isExclude;
    }

    public int getVendorId() {
        return mVendorId;
    }

    public void setVendorId(int mVendorId) {
        this.mVendorId = mVendorId;
    }

    public int getProductId() {
        return mProductId;
    }

    public void setProductId(int mProductId) {
        this.mProductId = mProductId;
    }

    public int getmClass() {
        return mClass;
    }

    public void setmClass(int mClass) {
        this.mClass = mClass;
    }

    public int getmSubclass() {
        return mSubclass;
    }

    public void setmSubclass(int mSubclass) {
        this.mSubclass = mSubclass;
    }

    public int getmProtocol() {
        return mProtocol;
    }

    public void setmProtocol(int mProtocol) {
        this.mProtocol = mProtocol;
    }

    public String getmManufacturerName() {
        return mManufacturerName;
    }

    public void setmManufacturerName(String mManufacturerName) {
        this.mManufacturerName = mManufacturerName;
    }

    public String getmProductName() {
        return mProductName;
    }

    public void setmProductName(String mProductName) {
        this.mProductName = mProductName;
    }

    public String getmSerialNumber() {
        return mSerialNumber;
    }

    public void setmSerialNumber(String mSerialNumber) {
        this.mSerialNumber = mSerialNumber;
    }

    public boolean isExclude() {
        return isExclude;
    }

    public void setExclude(boolean exclude) {
        isExclude = exclude;
    }

    @Override
    public String toString() {
        return "DeviceFilter{" +
                "mVendorId=" + mVendorId +
                ", mProductId=" + mProductId +
                ", mClass=" + mClass +
                ", mSubclass=" + mSubclass +
                ", mProtocol=" + mProtocol +
                ", mManufacturerName='" + mManufacturerName + '\'' +
                ", mProductName='" + mProductName + '\'' +
                ", mSerialNumber='" + mSerialNumber + '\'' +
                ", isExclude=" + isExclude +
                '}';
    }
    /**
     * 指定したクラス・サブクラス・プロトコルがこのDeviceFilterとマッチするかどうかを返す
     * mExcludeフラグは別途#isExcludeか自前でチェックすること
     * @param clasz
     * @param subclass
     * @param protocol
     * @return
     */
    private boolean matches(final int clasz, final int subclass, final int protocol) {
        return ((mClass == -1 || clasz == mClass)
                && (mSubclass == -1 || subclass == mSubclass) && (mProtocol == -1 || protocol == mProtocol));
    }

    /**
     * 指定したUsbDeviceがこのDeviceFilterにマッチするかどうかを返す
     * mExcludeフラグは別途#isExcludeか自前でチェックすること
     * @param device
     * @return
     */
    public boolean matches(final UsbDevice device) {
        if (mVendorId != -1 && device.getVendorId() != mVendorId) {
            return false;
        }
        if (mProductId != -1 && device.getProductId() != mProductId) {
            return false;
        }
/*		if (mManufacturerName != null && device.getManufacturerName() == null)
			return false;
		if (mProductName != null && device.getProductName() == null)
			return false;
		if (mSerialNumber != null && device.getSerialNumber() == null)
			return false;
		if (mManufacturerName != null && device.getManufacturerName() != null
				&& !mManufacturerName.equals(device.getManufacturerName()))
			return false;
		if (mProductName != null && device.getProductName() != null
				&& !mProductName.equals(device.getProductName()))
			return false;
		if (mSerialNumber != null && device.getSerialNumber() != null
				&& !mSerialNumber.equals(device.getSerialNumber()))
			return false; */

        // check device class/subclass/protocol
        if (matches(device.getDeviceClass(), device.getDeviceSubclass(), device.getDeviceProtocol())) {
            return true;
        }

        // if device doesn't match, check the interfaces
        final int count = device.getInterfaceCount();
        for (int i = 0; i < count; i++) {
            final UsbInterface intf = device.getInterface(i);
            if (matches(intf.getInterfaceClass(), intf.getInterfaceSubclass(), intf.getInterfaceProtocol())) {
                return true;
            }
        }

        return false;
    }

    /**
     * このDeviceFilterに一致してかつmExcludeがtrueならtrueを返す
     * @param device
     * @return
     */
    public boolean isExclude(final UsbDevice device) {
        return isExclude && matches(device);
    }

    /**
     * これって要らんかも, equalsでできる気が
     * @param f
     * @return
     */
    public boolean matches(final DeviceFilter f) {
        if (isExclude != f.isExclude) {
            return false;
        }
        if (mVendorId != -1 && f.mVendorId != mVendorId) {
            return false;
        }
        if (mProductId != -1 && f.mProductId != mProductId) {
            return false;
        }
        if (f.mManufacturerName != null && mManufacturerName == null) {
            return false;
        }
        if (f.mProductName != null && mProductName == null) {
            return false;
        }
        if (f.mSerialNumber != null && mSerialNumber == null) {
            return false;
        }
        if (mManufacturerName != null && f.mManufacturerName != null
                && !mManufacturerName.equals(f.mManufacturerName)) {
            return false;
        }
        if (mProductName != null && f.mProductName != null
                && !mProductName.equals(f.mProductName)) {
            return false;
        }
        if (mSerialNumber != null && f.mSerialNumber != null
                && !mSerialNumber.equals(f.mSerialNumber)) {
            return false;
        }

        // check device class/subclass/protocol
        return matches(f.mClass, f.mSubclass, f.mProtocol);
    }

    @Override
    public boolean equals(final Object obj) {
        // can't compare if we have wildcard strings
        if (mVendorId == -1 || mProductId == -1 || mClass == -1
                || mSubclass == -1 || mProtocol == -1) {
            return false;
        }
        if (obj instanceof DeviceFilter) {
            final DeviceFilter filter = (DeviceFilter) obj;

            if (filter.mVendorId != mVendorId
                    || filter.mProductId != mProductId
                    || filter.mClass != mClass || filter.mSubclass != mSubclass
                    || filter.mProtocol != mProtocol) {
                return false;
            }
            if ((filter.mManufacturerName != null && mManufacturerName == null)
                    || (filter.mManufacturerName == null && mManufacturerName != null)
                    || (filter.mProductName != null && mProductName == null)
                    || (filter.mProductName == null && mProductName != null)
                    || (filter.mSerialNumber != null && mSerialNumber == null)
                    || (filter.mSerialNumber == null && mSerialNumber != null)) {
                return false;
            }
            if ((filter.mManufacturerName != null && mManufacturerName != null && !mManufacturerName
                    .equals(filter.mManufacturerName))
                    || (filter.mProductName != null && mProductName != null && !mProductName
                    .equals(filter.mProductName))
                    || (filter.mSerialNumber != null && mSerialNumber != null && !mSerialNumber
                    .equals(filter.mSerialNumber))) {
                return false;
            }
            return (filter.isExclude != isExclude);
        }
        if (obj instanceof UsbDevice) {
            final UsbDevice device = (UsbDevice) obj;
            if (isExclude
                    || (device.getVendorId() != mVendorId)
                    || (device.getProductId() != mProductId)
                    || (device.getDeviceClass() != mClass)
                    || (device.getDeviceSubclass() != mSubclass)
                    || (device.getDeviceProtocol() != mProtocol) ) {
                return false;
            }
/*			if ((mManufacturerName != null && device.getManufacturerName() == null)
					|| (mManufacturerName == null && device
							.getManufacturerName() != null)
					|| (mProductName != null && device.getProductName() == null)
					|| (mProductName == null && device.getProductName() != null)
					|| (mSerialNumber != null && device.getSerialNumber() == null)
					|| (mSerialNumber == null && device.getSerialNumber() != null)) {
				return (false);
			} */
/*			if ((device.getManufacturerName() != null && !mManufacturerName
					.equals(device.getManufacturerName()))
					|| (device.getProductName() != null && !mProductName
							.equals(device.getProductName()))
					|| (device.getSerialNumber() != null && !mSerialNumber
							.equals(device.getSerialNumber()))) {
				return (false);
			} */
            return true;
        }
        return false;
    }

}
